<template>
  <!--teleport把以下模板片段传送到 body 标签下-->
  <teleport to="body">
    <transition name="list-fade">
      <div class="playlist" v-show="visible && playlist.length" @click="hide">
        <div class="list-wrapper">
          <div class="list-header">
            <h1 class="title">
              <i class="icon" :class="modeIcon" @click.stop="changeMode"></i>
              <span class="text">{{ modeText }}</span>
            </h1>
          </div>
          <Scroll class="list-content" ref="scrollRef">
            <transition-group name="list" tag="ul" ref="listRef">
              <li
                class="item"
                v-for="song in sequenceList"
                :key="song.id"
                @click="selectItem(song.id)"
              >
                <!-- 当前播放歌曲标识 -->
                <i class="current" :class="getCurrentIcon(song)"> </i>
                <span class="text">{{ song.name }}</span>
                <span class="favorite" @click.stop="toggleFavorite(song)"
                  ><i :class="getFavoriteIcon(song)"></i
                ></span>
                <span
                  class="delete"
                  :class="{ disable: removing }"
                  @click.stop="removeSong(song)"
                  ><i class="icon-delete"></i
                ></span>
              </li>
            </transition-group>
          </Scroll>
          <div class="list-footer" @click.stop="hide">
            <span>关闭</span>
          </div>
        </div>
      </div>
    </transition>
  </teleport>
</template>

<script>
import Scroll from '@/components/base/scroll/scroll.vue'
import { computed, ref, nextTick, watch } from 'vue'
import { useStore } from 'vuex'
import useMode from './use-mode'
import useFavorite from './use-favorite'

export default {
  name: 'playlist',
  components: {
    Scroll
  },
  setup () {
    const store = useStore()

    const visible = ref(false)
    const removing = ref(false)
    const scrollRef = ref(null)
    const listRef = ref(null)

    // hooks
    const { modeIcon, modeText, changeMode } = useMode()
    const { toggleFavorite, getFavoriteIcon } = useFavorite()
    const playlist = computed(() => store.state.playlist)
    const sequenceList = computed(() => store.state.sequenceList)
    const currentSong = computed(() => store.getters.currentSong)

    // 切歌场景：快捷键，智能音响，播放控件上一首下一首
    watch(currentSong, () => {
      if (!visible.value) return
      scrollToCurrent()
    })
    const getCurrentIcon = (song) => {
      if (song.id === currentSong.value.id) {
        return 'icon-play'
      }
    }
    // 播放列表首次显示或重新显示
    const show = async () => {
      visible.value = true
      await nextTick()
      // playlist无法滚动bug
      scrollRef.value.scroll.refresh()
      scrollToCurrent()
    }
    // 滚动到当前播放歌曲
    const scrollToCurrent = () => {
      const index = sequenceList.value.findIndex(
        (item) => item.id === currentSong.value.id
      )
      const target = listRef.value.$el.children[index]
      scrollRef.value.scroll.scrollToElement(target, 300)
    }
    const hide = () => {
      visible.value = false
    }
    const removeSong = (song) => {
      // 防止过快删除
      if (removing.value) {
        return
      }
      removing.value = true
      store.dispatch('removeSong', song)
      if (!playlist.value.length) {
        hide()
      }
      setTimeout(() => {
        removing.value = false
      }, 300)
    }
    const selectItem = (id) => {
      const index = sequenceList.value.findIndex((item) => item.id === id)
      store.commit('setCurrentIndex', index)
      store.commit('setPlayingState', true)
    }
    return {
      visible,
      sequenceList,
      playlist,
      removing,
      scrollRef,
      listRef,
      removeSong,
      show,
      hide,
      getCurrentIcon,
      selectItem,
      // use-mode
      modeIcon,
      modeText,
      changeMode,
      // use-favorite
      getFavoriteIcon,
      toggleFavorite
    }
  }
}
</script>

<style lang="scss" scoped>
.playlist {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  background-color: $color-background-d;
  .list-wrapper {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    box-sizing: border-box;
    height: 50%;
    background-color: $color-highlight-background;
    .list-header {
      padding: 20px 30px 10px 20px;
      .icon {
        margin-right: 10px;
        font-size: 24px;
        color: $color-theme-d;
      }
      .text {
        flex: 1;
        font-size: $font-size-medium;
        color: $color-text-l;
      }
    }
    .list-content {
      padding: 0 30px;
      max-height: 240px;
      overflow: hidden;
      .item {
        display: flex;
        align-items: center;
        height: 40px;
        .current {
          flex: 0 0 20px;
          font-size: $font-size-small;
          color: $color-theme-d;
        }
        .text {
          flex: 1;
          font-size: $font-size-medium;
          color: $color-text-d;
        }
        .favorite {
          margin-right: 15px;
          font-size: $font-size-small;
          color: $color-theme;
          .icon-favorite {
            color: $color-sub-theme;
          }
        }
        .delete {
          font-size: $font-size-small;
          color: $color-theme;
          &.disable {
            color: $color-theme-d;
          }
        }
        &.list-enter-active,
        &.list-leave-active {
          transition: all 500ms;
        }
        &.list-enter-from,
        &.list-leave-to {
          height: 0 !important;
        }
      }
    }
    .list-footer {
      position: fixed;
      bottom: 0;
      left: 0;
      width: 100%;
      height: 40px;
      line-height: 40px;
      text-align: center;
      background: $color-background;
      color: $color-text-l;
    }
  }
  &.list-fade-enter-active,
  &.list-fade-leave-active {
    transition: all 1s;
  }

  &.list-fade-enter-from,
  &.list-fade-leave-to {
    opacity: 0;
    .list-wrapper {
      transform: translate(0, 100%);
    }
  }
}
</style>
